package org.voovan.jinflux;


import org.voovan.http.client.HttpClient;
import org.voovan.http.message.Response;
import org.voovan.jinflux.annotation.Measurement;
import org.voovan.jinflux.command.Query;
import org.voovan.jinflux.command.Write;
import org.voovan.jinflux.exception.InfluxdbException;
import org.voovan.jinflux.model.Point;
import org.voovan.jinflux.model.Resp;
import org.voovan.tools.TDateTime;
import org.voovan.tools.TEnv;
import org.voovan.tools.TPerformance;
import org.voovan.tools.TString;
import org.voovan.tools.json.JSON;
import org.voovan.tools.log.Logger;
import org.voovan.tools.pool.ObjectPool;
import org.voovan.tools.pool.PooledObject;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 类文字命名
 *
 * @author: helyho
 * voovan Framework.
 * WebSite: https://github.com/helyho/voovan
 * Licence: Apache v2 License
 */
public class JinfluxPool {
    ObjectPool<Jinflux> pool;
    private static int MIN_SIZE = TPerformance.getProcessorCount();
    private static int MAX_SIZE = TPerformance.getProcessorCount();

    public JinfluxPool(String host, String username, String password, Integer timeout, String database, Integer minSize, Integer maxSize) {
        this.pool = new ObjectPool<Jinflux>()
                .minSize(minSize)
                .maxSize(maxSize)
                .validator((jinflux) -> {
                    return jinflux.isConnect();
                }).supplier(() -> {
                    return new Jinflux(host, username, password, timeout, database);
                }).destory((jinflux) -> {
                    jinflux.close();
                    return true;
                }).create();
    }


    public JinfluxPool(String host, String username, String password, Integer timeout, Integer minSize, Integer maxSize) {
        this(host, username, password, timeout, null, minSize, maxSize);
    }

    public JinfluxPool(String host, String username, String password, Integer timeout, String database) {
        this(host, username, password, timeout, database, MIN_SIZE, MAX_SIZE);
    }

    public JinfluxPool(String host, String username, String password, Integer timeout) {
        this(host, username, password, timeout, null,  MIN_SIZE, MAX_SIZE);
    }


    public ObjectPool<Jinflux> getPool() {
        return this.pool;
    }

    public Jinflux getJinflux(long timeout, TimeUnit timeUnit) throws TimeoutException {
        Jinflux jinflux = null;
        timeout = TimeUnit.MILLISECONDS.convert(timeout, timeUnit);
        long start = System.currentTimeMillis();

        while(System.currentTimeMillis() - start <= timeout) {
            jinflux = this.pool.borrow();
            if (jinflux != null) {
                return jinflux;
            }
        }

        throw new TimeoutException("get httpclient timeout");
    }

    public Jinflux getJinflux() {
        return (Jinflux)this.pool.borrow();
    }

    public void restitution(Jinflux jinflux) {
        this.pool.restitution(jinflux);
    }
}
